﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BilibiliDM_PluginFramework;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Runtime.Serialization;

namespace Bob
{
[DataContract]
class Config {
    [DataMember(Order = 0)]
    public int filecount;
    [DataMember(Order = 1)]
    public string[] filenames { get; set; }
};
class CDMRecorder {
    private static CDMRecorder _instance = null;
    private System.Timers.Timer t;
    public CDMRecorder(string dbPath) {
        _instance = this;
        list = new List<JsonDataElement>();
        t = new System.Timers.Timer(5000);
        t.AutoReset = false;
        t.Elapsed += new System.Timers.ElapsedEventHandler(Timer_TimesUp);
        danmuBasePath = dbPath;
    }
    //! 弹幕的基目录
    private string danmuBasePath;
    //! 输出日志的文件
    private string outpath;
    //! 日志的种类
    private static string _category;
    //! 类型，房间号
    public static string category
    {
        get
        {
            return _category;
        }
        set
        {
            _category = value;
            if (_instance!=null) {
                _instance.Start();
            }
        }
    }
    private string outfilename;
    private string cfg_path;
    private Bob.Config config;

    private void MakeConfigFileNameAndPath(ref DateTime now) {
        string config_filename = string.Format("{0}{1:D2}{2:D2}_cfg.js", now.Year, now.Month, now.Day);
        cfg_path = danmuBasePath + category + "\\" + config_filename;
        ClassPluginMan.instance().Log("set config filename:" + cfg_path);
        // 判断对应的文件夹是否存在，如果不存在，则创建
        string path = danmuBasePath + category + "\\";
        Directory.CreateDirectory(path);
    }

    private void MakeOutPath(ref DateTime now) {
        outfilename = string.Format("{0}{1:D2}{2:D2}-{3}.js", now.Year, now.Month, now.Day, config.filecount);
        outpath = danmuBasePath + category + "\\" + outfilename;
    }

    private void InitJsFile() {
        using (FileStream fs2 = File.Open(outpath, FileMode.CreateNew, FileAccess.Write, FileShare.Read)) {
            string init = "[]";
            byte[] byteArray = System.Text.Encoding.Default.GetBytes(init);
            fs2.Write(byteArray, 0, byteArray.Length);
            fs2.Close();
        }
    }

    private void InitConfigFile(ref DateTime now) {
        config = new Bob.Config();
        config.filecount = 0;
        config.filenames = null;
        // 写入文件
        using (FileStream fs = System.IO.File.Open(cfg_path, FileMode.Create, FileAccess.Write, FileShare.Read)) {
            config.filecount = 1;
            MakeOutPath(ref now);
            config.filenames = new string[1] { outfilename };
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Bob.Config));
            serializer.WriteObject(fs, config);
        }
    }

    private void ReadConfigFile(DateTime now) {
        // System.IO.FileInfo fi = new System.IO.FileInfo(cfg_path);
        // 如果文件存在，读取文件内容
        using (FileStream fs = System.IO.File.Open(cfg_path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read)) {
            // 如果文件内容可用，读取
            fs.Seek(0, SeekOrigin.Begin);
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Bob.Config));
            config = serializer.ReadObject(fs) as Config;
            // 生成日志文件的输入路径
            MakeOutPath(ref now);
        }
    }

    //! 保存本地文件
    public bool Start() {
        DateTime now = DateTime.Now;
        MakeConfigFileNameAndPath(ref now);
        //  1.先检查配置打开文件是否存在
        if (File.Exists(cfg_path)) {
            ReadConfigFile(now);
        }
        else {
            // 如果不存在，则写入文件
            InitConfigFile(ref now);
        }
        // 打开个 outpath
        if (!File.Exists(outpath)) {
            InitJsFile();
        }
        t.Start();
        return true;
    }
    public bool Stop() {
        t.Stop();
        return true;
    }
    private List<JsonDataElement> list;
    public void WriteDanMu(ReceivedDanmakuArgs e) {
        DanmakuModel dm = e.Danmaku;
        JsonDataElement ele = new JsonDataElement();
        ele.MsgType = dm.MsgType;
        // 如果是评论
        if (dm.MsgType == MsgTypeEnum.Comment) {
            ele.CommentUser = dm.CommentUser;
            ele.CommentText = dm.CommentText;
        }
        else if (dm.MsgType == MsgTypeEnum.GiftSend) {
            ele.GiftName = dm.GiftName;
            ele.GiftNum = dm.GiftNum;
            ele.GiftUser = dm.GiftUser;
        }
        else if (dm.MsgType == MsgTypeEnum.LiveStart) {
            ele.roomID = dm.roomID;
        }
        else if (dm.MsgType == MsgTypeEnum.LiveEnd) {
            ele.roomID = dm.roomID;
        }
        else return;
        ele.dt = DateTime.Now;
        list.Add(ele);
    }
    public static string datePatt = @"M/d/yyyy hh:mm:ss";

    private void CheckIsFileTooBig(int nFileLen) {
        //! 检查文件是否过大，如果过大，则更换文件
        if (nFileLen > 10240) {
            DateTime now = DateTime.Now;
            config.filecount = config.filecount + 1;
            List<string> list = new List<string>(config.filenames);
            MakeOutPath(ref now);
            list.Add(outfilename);
            config.filenames = list.ToArray();
            MakeConfigFileNameAndPath(ref now);
            using (FileStream fscfg = System.IO.File.Open(cfg_path, FileMode.Create, FileAccess.Write, FileShare.Read)) {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Bob.Config));
                serializer.WriteObject(fscfg, config);
                outpath = danmuBasePath + category + "\\" + outfilename;
            }
            if (!File.Exists(outpath)) {
                InitJsFile();
            }
        }
    }

    private void WriteDanmuToFile() {
        //! 检查日期是否过了一天
        if (File.Exists(outpath)) {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(JsonMsgModel[]));
            using (FileStream fs = File.Open(outpath, FileMode.Open, FileAccess.Write, FileShare.Read)) {
                fs.Seek(-1, SeekOrigin.End);
                JsonMsgList msglist = new JsonMsgList();
                List<JsonMsgModel> modellist = new List<JsonMsgModel>();
                for (int i = 0; i < list.Count; i++) {
                    JsonDataElement ele = list[i];
                    string json = "";
                    DateTime dlocal = ele.dt.ToLocalTime();
                    string strDate = dlocal.ToString(datePatt);
                    JsonMsgModel model = new JsonMsgModel();
                    model.t = strDate;
                    if (ele.MsgType == MsgTypeEnum.Comment) {
                        model.y = "c";
                        model.u = ele.CommentUser;
                        model.c = ele.CommentText;
                    }
                    if (ele.MsgType == MsgTypeEnum.GiftSend) {
                        model.y = "g";
                        model.u = ele.GiftUser;
                        model.c = string.Format("赠送{0} x {1}", ele.GiftUser, ele.GiftName);
                    }
                    if (ele.MsgType == MsgTypeEnum.LiveStart) {
                        model.y = "ls";
                        model.u = "管理";
                        model.c = string.Format("房间{0}直播开始", ele.roomID);
                    }
                    if (ele.MsgType == MsgTypeEnum.LiveEnd) {
                        model.y = "le";
                        model.u = "管理";
                        model.c = string.Format("房间{0}直播结束", ele.roomID);
                    }
                    if (model.c == "") {
                        continue;
                    }
                    modellist.Add(model);
                    //byte[] byteJson = System.Text.Encoding.Default.GetBytes(json);
                    //fs.Write(byteJson, 0, byteJson.Length);
                }
                msglist.models = modellist.ToArray();
                using (MemoryStream sstream = new MemoryStream()) {
                    serializer.WriteObject(sstream, msglist.models);
                    Byte[] bytes = sstream.ToArray();
                    long pos = fs.Position;
                    if (pos != 1) {
                        bytes[0] = (Byte)',';
                        fs.Write(bytes, 0, bytes.Length);
                    }
                    else {
                        fs.Write(bytes, 1, bytes.Length - 1);
                    }
                }
                list.Clear();
                int nFileLen = (int)fs.Position;
                CheckIsFileTooBig(nFileLen);
            }
        }
    }

    private void Timer_TimesUp(object sender, System.Timers.ElapsedEventArgs e) {
        //到达指定时间5秒触发该事件输出 Hello World!!!!
        if (category!="") {
            if (list.Count != 0) {
                if (outpath != "") {
                    //! 打开文件。
                    WriteDanmuToFile();
                }
            }
            CheckIsDateUpdate();
        }
        t.Start();
    }

    private void CheckIsDateUpdate() {
        DateTime now = DateTime.Now;
        string config_filename = string.Format("{0}{1:D2}{2:D2}_cfg.js", now.Year, now.Month, now.Day);
        string temp_cfgpath = danmuBasePath + category + "\\" + config_filename;
        if (temp_cfgpath != cfg_path) {
            // 先把当前config 清空，然后初始化
            MakeConfigFileNameAndPath(ref now);
            if (!File.Exists(cfg_path)) {
                // 如果不存在，则写入文件
                InitConfigFile(ref now);
            }
            // 打开个 outpath
            if (!File.Exists(outpath)) {
                InitJsFile();
            }
        }
    }

}
}
